﻿using Cherry.Agile.Distributed.Queue;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Cherry.Agile.Distributed.Queue.Impl
{
    public class RAMQueueRepository : IQueueRepository
    {
        static Dictionary<string, Block> datas = new Dictionary<string, Block>();

        public RAMQueueRepository(System.Collections.Specialized.NameValueCollection @params)
        {

        }

        public string Get(string name, int? index,out int newIndex)
        {
            lock (name)
            {
                Block lst;
                if (!datas.TryGetValue(name, out lst))
                {
                    lst = new Block(name);
                    datas.Add(name,lst);
                }
                return lst.Get(index, out newIndex);
            }
        }

        public int Set(string name, string data)
        {
            lock (name)
            {
                Block lst;
                if (!datas.TryGetValue(name, out lst))
                {
                    lst = new Block(name);
                    datas.Add(name, lst);
                }
                return lst.Set(data);
            }
        }

        public void Max(int length)
        {
            throw new NotImplementedException();
        }
    }

    class Block
    {
        public Block(string name)
        {
            this.Name = name;
            this.Datas = new List<string>();
            Init();
        }

        void Init()
        {
            for (int i = Datas.Count; i < Max; i++)
            {
                Datas.Add(null);
            }
        }

        string this[int index]
        {
            get
            {
                if (index >= Max)
                    return string.Empty;
                return Datas[index];
            }
            set
            {
                Datas[index] = value;
                WIndex += 1;
            }
        }

        public string Get(int? index,out int newIndex)
        {
            newIndex = -1;
            if (index.HasValue)
                return this[index.Value];

            if (RIndex == WIndex)
                return null;

            newIndex = RIndex % Max;
            var item = Datas[newIndex];
            
            RIndex += 1;
            return item;
        }

        public int Set(string value, int? index = null)
        {
            if (index.HasValue)
            {
                this[index.Value] = value;
                return index.Value;
            }
            Datas[WIndex % Max] = value;
            WIndex += 1;
            return WIndex - 1;
        }


        volatile int RIndex;

        volatile int WIndex;

        public volatile int Max = 1000;

        public string Name { get; private set; }

        List<string> Datas { get; set; }
    }
}
